/* 
 * Bitmain Tech, Home of Professional Bitmain Tech
 * Copyright 2014 Bitmain Tech Inc. and/or its affiliates and other contributors
 * as indicated by the @author tags. All rights reserved.
 * See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 */
package com.bitmain.mmst.feature.mybatis.handler;

import java.sql.Array;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.TypeException;

/**
 * 数组类型字段转换
 *
 * @author Kweny - enkun.jiang@bitmain.com
 * @since 2015年12月21日
 *
 */
public class ArrayTypeHandler extends BaseTypeHandler<Object[]> {
	private static final String TYPE_NAME_INTEGER = "integer";
	private static final String TYPE_NAME_BIGINT = "bigint";
	private static final String TYPE_NAME_NUMERIC = "numeric";
	private static final String TYPE_NAME_VARCHAR = "varchar";
	private static final String TYPE_NAME_BOOLEAN = "boolean";

	/* (non-Javadoc)
	 * @see org.apache.ibatis.type.BaseTypeHandler#setNonNullParameter(java.sql.PreparedStatement, int, java.lang.Object, org.apache.ibatis.type.JdbcType)
	 */
	@Override
	public void setNonNullParameter(PreparedStatement ps, int i, Object[] parameter, JdbcType jdbcType) throws SQLException {
		String typeName = null;
		if (parameter instanceof String[]) {
			typeName = TYPE_NAME_VARCHAR;
		} else if (parameter instanceof Integer[]) {
			typeName = TYPE_NAME_INTEGER;
		} else if (parameter instanceof Long[]) {
			typeName = TYPE_NAME_BIGINT;
		} else if (parameter instanceof Double[]) {
			typeName = TYPE_NAME_NUMERIC;
		} else if (parameter instanceof Boolean[]) {
			typeName = TYPE_NAME_BOOLEAN;
		}
		
		if (typeName == null) {
			throw new TypeException("parameter type error: " + parameter.getClass().getName());
		}
		
		Connection conn = ps.getConnection();
		Array array = conn.createArrayOf(typeName, parameter);
		ps.setArray(i, array);
	}

	/* (non-Javadoc)
	 * @see org.apache.ibatis.type.BaseTypeHandler#getNullableResult(java.sql.ResultSet, java.lang.String)
	 */
	@Override
	public Object[] getNullableResult(ResultSet rs, String columnName) throws SQLException {
		return getArray(rs.getArray(columnName));
	}

	/* (non-Javadoc)
	 * @see org.apache.ibatis.type.BaseTypeHandler#getNullableResult(java.sql.ResultSet, int)
	 */
	@Override
	public Object[] getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
		return getArray(rs.getArray(columnIndex));
	}

	/* (non-Javadoc)
	 * @see org.apache.ibatis.type.BaseTypeHandler#getNullableResult(java.sql.CallableStatement, int)
	 */
	@Override
	public Object[] getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
		return getArray(cs.getArray(columnIndex));
	}
	
	private Object[] getArray(Array array) {
		if (array == null) {
			return null;
		}
		try {
			return (Object[]) array.getArray();
		} catch (Exception e) {
			return null;
		}
	}

}
